package com.antlr;



import com.gen.ExprBaseVisitor;
import com.gen.ExprLexer;
import com.gen.ExprParser;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CodePointCharStream;
import org.antlr.v4.runtime.CommonTokenStream;

import java.util.Objects;



public class EvalExprVisitor extends ExprBaseVisitor<Integer> {

    static int result = 0;

    public void visitRoot(String compute){
        // 构建字符流
        CodePointCharStream input = CharStreams.fromString(compute);
        // 从字符流分析词法， 解析为token
        ExprLexer lexer = new ExprLexer(input);
        // 从token进行分析
        ExprParser parser = new ExprParser(new CommonTokenStream( lexer) );
        result = this.visit(parser.expr());
    }


    /**
     * expr:	expr ('*'|'/') expr
     *     |	expr ('+'|'-') expr
     *     |	INT
     *     |	'(' expr ')'
     * @param ctx the parse tree
     * @return
     */
    /**
     * expr ('*'|'/') expr
     */
    @Override
    public Integer visitMultiOrDiv(ExprParser.MultiOrDivContext ctx) {
        Integer op1 = visit(ctx.expr(0));
        Integer op2 = visit(ctx.expr(1));

        String operator = ctx.getChild(1).getText();
        if (Objects.equals(operator, "*")){
            return op1 * op2;
        }
        if (Objects.equals(operator, "/")){
            return op1 / op2;
        }

        return 0;
    }

    /**
     * expr ('+'|'-') expr
     */
    @Override
    public Integer visitAddOrSub(ExprParser.AddOrSubContext ctx) {
        Integer op1 = visit(ctx.expr(0));
        Integer op2 = visit(ctx.expr(1));

        String operator = ctx.getChild(1).getText();
        if (Objects.equals(operator, "+")){
            return op1 + op2;
        }

        if (Objects.equals(operator, "-")){
            return op1 - op2;
        }

        return 0;
    }

    /**
     *
     * @param ctx the parse tree
     * @return
     */
    @Override
    public Integer visitSingle(ExprParser.SingleContext ctx) {
        return visit(ctx);
    }

    /**
     * INT
     * @return
     */
    @Override
    public Integer visitLieteral(ExprParser.LieteralContext ctx) {
        return Integer.valueOf(ctx.INT().getText());
    }
}
